package com.xie.smfs.util;

import com.google.gson.Gson;
import com.google.gson.JsonSyntaxException;
import com.google.gson.reflect.TypeToken;
import com.xie.smfs.client.data.ClientDataManager;
import net.minecraft.registry.Registries;
import com.xie.smfs.common.events.PlayerEvents;
import net.fabricmc.api.EnvType;
import net.fabricmc.api.Environment;
import net.minecraft.client.MinecraftClient;
import com.google.gson.Gson;
import com.google.gson.reflect.TypeToken;
import java.lang.reflect.Type;
import net.minecraft.resource.ResourceManager;
import net.minecraft.util.Identifier;
import net.minecraft.world.World;
import net.minecraft.entity.player.PlayerEntity;
import net.minecraft.nbt.NbtCompound;
import net.minecraft.nbt.NbtList;
import net.minecraft.nbt.NbtString;
import net.minecraft.nbt.NbtElement;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.InputStreamReader;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.Collections;

@Environment(EnvType.CLIENT)
public class TutorialManager {
    static {
        ClientDataManager.init();
    }
    private static final Logger LOGGER = LoggerFactory.getLogger(TutorialManager.class);
    private static TutorialManager instance;
    private final List<TutorialEntry> tutorials;
    private final List<EventStoryEntry> eventStories;
    private int currentDay;

    /**
     * 私有构造方法，初始化当前天数、教程和事件剧情数据
     */
    private TutorialManager() {
        this.currentDay = calculateCurrentDay();
        this.tutorials = loadTutorials();
        this.eventStories = loadEventStories();
    }

    /**
     * 获取TutorialManager的单例实例
     * @return 唯一的TutorialManager实例
     */
    public static TutorialManager getInstance() {
        if (instance == null) {
            instance = new TutorialManager();
        }
        return instance;
    }

    /**
     * 计算当前游戏内天数
     * @return 当前游戏内天数，基于世界时间计算
     */
    private int calculateCurrentDay() {
        MinecraftClient client = MinecraftClient.getInstance();
        World world = client.world;
        if (world != null) {
            long totalTime = world.getTime();
            int day = (int)(totalTime / 24000) + 1;
            return Math.max(day, 1);
        } else {
            LOGGER.warn("世界未加载，使用默认天数1");
            return 1;
        }
    }

    /**
     * 从JSON文件加载教程数据
     * @return 教程条目列表，加载失败时返回默认数据
     */
    private List<TutorialEntry> loadTutorials() {
        List<TutorialEntry> loadedTutorials = new ArrayList<>();

        try {
            ResourceManager resourceManager = MinecraftClient.getInstance().getResourceManager();
            // 正确的资源路径应该在 assets 目录下
            Identifier tutorialResource = new Identifier("smfs", "tutorials/tutorials.json");

            if (resourceManager.getResource(tutorialResource).isPresent()) {
                InputStreamReader reader = new InputStreamReader(
                        resourceManager.open(tutorialResource)
                );
                Type tutorialListType = new TypeToken<List<TutorialEntry>>(){}.getType();
                loadedTutorials = new Gson().fromJson(reader, tutorialListType);
                LOGGER.info("成功加载 {} 个教程条目", loadedTutorials.size());
            } else {
                LOGGER.warn("教程文件未找到: {}", tutorialResource);
                // 提供默认的教程数据作为回退
                loadedTutorials = createDefaultTutorials();
            }
        } catch (Exception e) {
            LOGGER.error("加载教程数据失败", e);
            // 提供默认数据作为回退
            loadedTutorials = createDefaultTutorials();
        }

        return loadedTutorials;
    }

    /**
     * 创建默认教程数据作为加载失败时的回退
     * @return 默认教程条目列表
     */
    private List<TutorialEntry> createDefaultTutorials() {
        List<TutorialEntry> defaultTutorials = new ArrayList<>();
        defaultTutorials.add(new TutorialEntry(1, "加载失败。"));
        return defaultTutorials;
    }

    /**
     * 创建默认事件剧情数据作为加载失败时的回退
     * @return 默认事件剧情条目列表
     */
    private List<EventStoryEntry> createDefaultEvents() {
        List<EventStoryEntry> defaultEvents = new ArrayList<>();
        // 默认事件：驾驭鬼眼剧情（请在event_stories.json中配置正确的事件）
        EventStoryEntry.TriggerConditions conditions = new EventStoryEntry.TriggerConditions(
            1, // 最小天数：第一天
            Collections.singletonList("smfs:guiyan"), // 修正鬼眼物品ID为实际使用的ID
            false // 是否可重复：否
        );
        defaultEvents.add(new EventStoryEntry(
            "ghost_eye_event", 
            "默认事件剧情。",
            conditions
        ));
        return defaultEvents;
    }

    /**
     * 从JSON文件加载事件剧情数据
     * @return 事件剧情条目列表，加载失败时返回默认事件
     */
    private List<EventStoryEntry> loadEventStories() {
        List<EventStoryEntry> loadedEvents = new ArrayList<>();

        try {
            ResourceManager resourceManager = MinecraftClient.getInstance().getResourceManager();
            Identifier eventResource = new Identifier("smfs", "tutorials/event_stories.json");

            if (resourceManager.getResource(eventResource).isPresent()) {
                InputStreamReader reader = new InputStreamReader(
                        resourceManager.open(eventResource)
                );
                Type eventListType = new TypeToken<List<EventStoryEntry>>(){}.getType();
                loadedEvents = new Gson().fromJson(reader, eventListType);
                LOGGER.info("成功加载 {} 个事件剧情条目", loadedEvents.size());
            } else {
            LOGGER.warn("事件剧情文件未找到: {}", eventResource);
            loadedEvents = createDefaultEvents();
        }
        } catch (Exception e) {
        LOGGER.error("加载事件剧情数据失败", e);
        loadedEvents = createDefaultEvents();
    }

        return loadedEvents;
    }

    /**
     * 获取当前应显示的剧情内容
     * 根据查看次数决定显示每日剧情还是事件剧情
     * @return 剧情文本内容
     */
    private String getPlayerName() {
        MinecraftClient client = MinecraftClient.getInstance();
        PlayerEntity player = client.player;
        return player != null ? player.getName().getString() : "Player";
    }
    
    public String getCurrentStory() {
        this.currentDay = calculateCurrentDay(); // 动态更新当前天数
        
        int viewCount = getViewCount();
        String playerName = getPlayerName();
        
        // 第一次查看：显示每日剧情
        if (viewCount == 0) {
            String dailyStory = getDailyStory().replace("{playerName}", playerName);
            incrementViewCount();
            return dailyStory;
        }
        // 第二次及以后查看：检查事件剧情
        else {
            EventStoryEntry eventStory = getValidEventStory();
            if (eventStory != null) {
                if (!eventStory.getTriggerConditions().isRepeatable()) {
                    addShownEvent(eventStory.getId());
                }
                return eventStory.getStory().replace("{playerName}", playerName);
            }
            return getDailyStory().replace("{playerName}", playerName);
        }
    }

    /**
     * 获取当前天数对应的每日剧情
     * @return 每日剧情文本内容
     */
    public String getDailyStory() {
        if (tutorials.isEmpty()) {
            return "暂无剧情内容";
        }

        // 找到对应天数的每日剧情
        for (TutorialEntry entry : tutorials) {
            if (entry.getDay() == currentDay) {
                return entry.getStory();
            }
        }

        // 如果没有找到对应天数的，返回最后一个或第一个
        if (currentDay > tutorials.get(tutorials.size() - 1).getDay()) {
            return tutorials.get(tutorials.size() - 1).getStory();
        } else {
            return tutorials.get(0).getStory();
        }
    }

    /**
     * 获取当前剧情查看次数
     * @return 查看次数
     */
private int getViewCount() {
        return ClientDataManager.getTutorialViewCount();
    }

    /**
     * 增加剧情查看次数
     */
private void incrementViewCount() {
        ClientDataManager.incrementTutorialViewCount();
    }

    /**
     * 获取玩家已查看的事件剧情ID列表
     * @return 已显示事件剧情ID的列表
     */
    private List<String> getShownEvents() {
        String shownEventsJson = ClientDataManager.getShownEvents();
        try {
            return new Gson().fromJson(shownEventsJson, new TypeToken<List<String>>(){}.getType());
        } catch (JsonSyntaxException e) {
            return new ArrayList<>();
        }
    }

    /**
     * 将事件剧情ID添加到已查看列表
     * @param eventId 已显示事件剧情的ID
     */
    private void addShownEvent(String eventId) {
        List<String> shownEvents = getShownEvents();
        if (!shownEvents.contains(eventId)) {
            shownEvents.add(eventId);
            ClientDataManager.setShownEvents(new Gson().toJson(shownEvents));
        }
    }

    private EventStoryEntry getValidEventStory() {
        MinecraftClient client = MinecraftClient.getInstance();
        if (client.player == null || eventStories.isEmpty()) return null;

        PlayerEntity player = client.player;
        List<String> shownEvents = getShownEvents();

        for (EventStoryEntry event : eventStories) {
            EventStoryEntry.TriggerConditions conditions = event.getTriggerConditions();

            // 检查事件是否已显示且不可重复
            if (!conditions.isRepeatable() && shownEvents.contains(event.getId())) {
                continue;
            }

            // 检查最小天数条件
            if (conditions.getMinDay() > currentDay) {
                continue;
            }

            // 检查所需物品
            if (!hasRequiredItems(player, conditions.getRequiredItems())) {
                continue;
            }

            return event;
        }
        return null;
    }

    private boolean hasRequiredItems(PlayerEntity player, List<String> requiredItems) {
        if (requiredItems.isEmpty()) return true;

        for (String itemId : requiredItems) {
            boolean found = false;
            for (int i = 0; i < player.getInventory().size(); i++) {
                if (Registries.ITEM.getKey(player.getInventory().getStack(i).getItem()).toString().equals(itemId)) {
                    found = true;
                    break;
                }
            }
            if (!found) return false;
        }
        return true;
    }

    public int getCurrentDay() {
        return currentDay;
    }

    public static class TutorialEntry {
        private int day;
        private String story;

        // 添加无参构造函数用于Gson反序列化
        public TutorialEntry() {}

        public TutorialEntry(int day, String story) {
            this.day = day;
            this.story = story;
        }

        public int getDay() { return day; }
        public String getStory() { return story; }
    }
}